# Author:Xiao yang
# 时间：1009-week06

stu_id = [1001,1002,1003,1004,1008,1001,1009,1010,1001,]
stu_ids = [10001,10002,10003,10004,10008,10001,10009,10010,10001,]
# 1. copy（）很重要
# 思考？赋值是真正的复制么？赋值（=） <=> copy? 结果：不等价

stu_id_matedata = stu_id
print("stu_id:",stu_id,'\n','stu_id_matedata:',stu_id_matedata)

# 实验1.赋值
# stu_id.pop(1)
# print("stu_id:",stu_id,'\n','stu_id_matedata:',stu_id_matedata)
# 实验2.copy（）
# stu_id_matedata = stu_id.copy()
# stu_id.pop(1)
# print("stu_id:",stu_id,'\n','stu_id_matedata:',stu_id_matedata)
# 实验3.切片实验复制
stu_id_matedata = stu_id[:]
stu_id.pop(1)
print("stu_id:",stu_id,'\n','stu_id_matedata:',stu_id_matedata)

print()

# 引申：赋值、浅拷贝、深拷贝
# ①举例：定义一个新列表
l1 = [1, 2, 3, 4, 5]
# 对l2赋值
l2 = l1
print(l1)
l2[0] = 100
print(l1)
# 可以看到，更改赋值后的L2后L1同样也会被更改，看似简单的“复制”，
# 在Python中，列表属于可变对象，
# 而对可变对象的复制 其实就是将列表的内存空间类似C中的指针再次指向新的变量名，
# 而不是诸如字符串 这种不可变对象 在复制时会创建新的内存空间进行赋值。
# 即 此时L1和L2指向的是同一片内存空间    那么怎么实现真正复制呢？

print()
# ②浅拷贝 ===> 5种方法 ===>> 1.切片；2.模块copy；3.利用list()；4.利用列表方法extend；5.利用列表推导

import copy
# 定义一个新列表
L0 = [1, 2, 3, 4, 5]
print(L0)
print('-'*40)

# 1.切片；
L1 = L0[:]
L1[0] = 100
print(L0)

# 2.模块copy；
import copy
L2 = copy.copy(L0)
L2[0] = 100
print(L0)

# 3.利用list()；
L3 = list(L0)
L3[0] = 100
print(L0)

# 4.利用列表方法extend；
L4 = []
L4.extend(L0)
L4[0] = 100
print(L0)

# 5.利用列表推导
L5 = [i for i in L0]
L5[0] = 100
print(L0)

print()
# 可以看到最终的打印结果都是[1, 2, 3, 4, 5]，我们复制成功了
# 但是如果为了条件需要 列表中元素为不可变对象呢？
# 因为如果列表中的元素为可变对象，在复制时有会发生对象的引用，而不是新建内存空间进行引用，
# 比如：以下列表情况

L0 = [1, 2, [3], 4, 5]
print(L0)
L2 = L0[:]
L2[2][0] = 100
print(L0)

# 可以看到，当列表L0中含有可变对象时，
# 对复制后的L1进行改变其中可变对象元素L2[2]时，L0中的可变对象L0[2]也发生了改变，
# 那么怎么实现真正的完全的拷贝呢？

print()
# ③深拷贝 ===>利用copy模块中的deepcopy进行深拷贝
import copy
L0 = [1, 2, [3], 4, 5]
print(L0)
L2 = copy.deepcopy(L0)
L2[2][0] = 100
print(L2)
print(L0)